<template>
  <div>
    <h3>======set的使用=======</h3>
    说明<span class="myred">数据发生变换,视图层不变需要用$set</br> vue2是监听不到对象新增/删除属性,数组下标改变内容.就需要$set方法
      它的使用方法 this.$set(数组/对象,下标/key,新值)</br>

      解释为什么监听不到(vue2响应式的原理):在页面或者是组件加载的时候
      会调用Object.defineProperty(嘚烦噗若破忒)方法,给data里面的每一个属性添加getter和setter方法进行数据的劫持.
      当数据发生改变的时候,会触发set方法,然后去更新视图层.
      但是因为对象新增的属性.初始化的时候没有,所以才监听不到</br>


      <B>原理</B>当时我也对这个方法挺好奇的,还去看了下vue源码 在里面的时候是判断了一下:</br>如果是数组的话,就调用了他的变异方法splice,其实我觉得是一个对数组原型链的修改.
      vue中调用的数组方法.不是数字本身的方法.是vue进行了改写的.改写了好像是七个吧.当判断是数组的时候,就调用splice引起视图层变更</br>

      如果是对象的话,相当于又重新调用了Object.definedProperty,给新增进来的属性,添加了getter和setter方法.后面视图层就能变更并且响应式了</br>
      <B>修改了哪七个?</B> push unshift pop sort splice reverse shift 同时这七个也是能够改变原数组的方法
      splice方法(下标,删除的个数,新增谁,新增谁.....)</br>
      <span>数组.splice(下标,删除几个,新增谁,新增谁)</span></br>
      <span>原数组var arr = [2,3,4,5,6]</span></br>
      <span>想要变成[2,3,9,5,6] =====>arr.splice(2,1,9) 数组元素的修改</span></br>
      <span>想要变成[2,3,4,9,5,6] =====>arr.splice(2,0,9) 数组元素的新增</span></br>
      <span>想要变成[2,3,5,6] =====>arr.splice(2,1) 数组元素的删除</span></br>
    </span>

    新用户名:<input type="text" placeholder="请输入新的用户名" v-model="newName" />
    <button @click="UpdName">修改</button>
    <button @click="UpdObj">修改Obj的值</button>
    <h4>展示用户信息</h4>
    <ul>
      <li v-for="(item, index) in person" :key="index">
        {{ item.name }}--{{ item.age }}----{{ item.friends }}
      </li>
    </ul>
  </div>
</template>

<script>
var arr1 = [123]
export default {

  data () {
    return {
      newName: "",
      person: [
        {
          name: "苏明",
          age: "32"
        },
        {
          name: "邵琦特",
          age: "18"
        }
      ],
      testObjDef: {
        name: "张三",
        age: 18
      }
    }
  },
  methods: {
    UpdName () {
      // this.$set(数组/对象,下标/key,新值)

      // 数组
      // this.person[1] = { name: this.newName, age: 23 } //无效
      // this.$set(this.person, 1, { name: this.newName, age: 23 });
      // 对象
      // this.person[1].name = this.newName //已有属性可以响应式
      // this.person[1].friends = "尚英豪" //不存在属性不可以 因为初始化没有被Object.definedProperty添加监听
      this.$set(this.person[1], 'friends', "尚英豪");
      // console.log(this.person);
    },
    UpdObj () {
      // this.testObjDef.age = 40;
      // console.log(this.testObjDef.age, "是什么")
      this.testObjDef.age;
    },
    watch (obj, propName) {
      let value = obj[propName];
      Object.defineProperty(obj, propName, {
        get () {
          console.log(`获取 ${propName}: ${value}`);
          return value;
        },
        set (newValue) {
          console.log(`设置 ${propName} 为 ${newValue}`);
          value = newValue;
        }
      });
      return obj;

    }
  },
  created () {

    this.watch(this.testObjDef, 'age');

    console.log("普通数组", arr1)
    console.log("vue数组", this.person)

  }

}
</script>
<style scoped></style>
